<template>
  <div class="switch-page" 
       v-loading="loading" 
       :element-loading-text="loadingText">
    <div class="switch-left column">
      <el-form style="width:100%;padding:1rem;padding-bottom:.5rem;" label-width="60px">
        <div class="between center" style="margin-bottom:10px;">
          <span>设置搜索查询</span>
        </div>
        <el-form-item label="串口">
          <el-select v-model="equipForm.portModel" placeholder="请选择" size="small" style="width:100%;">
            <el-option
              v-for="item in portList"
              :key="item.value"
              :label="item.label"
              :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-row>
          <el-col :span="24">
            <el-form-item label="波特率">
              <el-select v-model="equipForm.rateModel" placeholder="请选择" size="mini" class="select">
                <el-option
                  v-for="(item,index) in rate"
                  :key="index"
                  :label="item"
                  :value="item">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="ID号" size="mini">
                <el-input type="textarea" v-model="resetIds" placeholder="请输入ID号(逗号隔开)"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <div>
            IDS:{{copyResetIds === ''?'待设置':copyResetIds}}
        </div>
      </el-form>
      <div class="row-center">
         <el-button size="small" type="primary" style="width:90%;" @click="equipSnPre">开始分配ID</el-button>
      </div>
    </div>
    <div class="switch-right">
        <el-table
        :data="tableData"
        style="width: 100%"
        id="out-table">
        <el-table-column
            prop="sn"
            label="SN">
        </el-table-column>
        <el-table-column
            prop="id"
            label="ID">
        </el-table-column>
        </el-table>
        <div class="row-center" style="margin-top:3rem;">
            <el-button type="primary" plain size="mini" @click="exportExcel">导出为Csv</el-button>
            <el-button type="primary" size="mini" @click="endWhileSn">结束配置</el-button>
            <el-button type="primary" size="mini" @click="confirmClear">清空表格</el-button>
        </div>
    </div>
  </div>
</template>


<script>
import EquipList from '../switch/children/EquipList'
import Bus from '../../utils/bus.js'
export default {
  components:{
    EquipList
  },
  data(){
    return {
      copyResetIds:'',
      serial_number:[],
      tableData: [],
      resetIds:'',
      equipForm:{
        rateModel:9600,
        byteModel:8,
        portModel:'',
        stopModel:1,
        checkModel:'N',
      },
      rate:[600,1200,2400,4800,9600,14400,19200,28800,38400,57600,115200,230400,460800],//波特率
      checkList:[
        {value: 'N',label: '无校验'},
        {value: 'E',label: '奇校验'},
        {value: 'O',label: '偶校验'},
        {value: '0',label: '0校验'},
        {value: '1',label: '1校验'}
      ],
      stopList:[
        {value: 1,label: '1位'},
        {value: 1.5,label: '1.5位'},
        {value: 2,label: '2位'}
      ],
      rateList:[2400,4800,9600,19200,38400,57600,115200],
      byteList:[7,8,9],
      portList:[],
      configName:'',
      editConfig:true,
      eid:0,
      ids:[],
      settingForm:{
        rate:1,
        eid:this.eid,
        autoUpload:true,
        background:true
      },
      loading:false,
      equipList:[],
      config:{},
      timer:null,
      loadingText:"搜索设备中",
      all:'1',
      chooseConfigName:"未选择配置",
      whileSnTimer:null
    }
  },
  created(){
    this.getPortList();
    clearInterval(this.timer);
    this.timer = setInterval(()=>{
      this.getPortList();
    },2000)
    Bus.$on('duankai', () => {  
        this.config = {};
        this.equipList = [];
    });
  },
  beforeDestroy(){
    clearInterval(this.timer);
    clearInterval(this.whileSnTimer);
  },
  watch:{
      resetIds(val){
        this.resetIds = val.replace(/，/g,",");
      }
  },
  methods:{
    confirmClear(){
      this.$confirm('确认清空表格?').then(_=>{
        tableData = []
      })
    },
    getNowTime(){
      let date = new Date();
      date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
      return date.toJSON().replace(/[TZ]/g, ' ').substr(0,19);
      //2021-12-08 11:51:20
    },
    arr2CsvString(arr){
      if(arr.length === 0){
        return '';
      }
      const headers = Object.keys(arr[0]);
      let finalString = headers.join(',')+'\n';
      for(const item of arr){
        finalString += Object.values(item).join(',')+'\n'
      }
      return finalString;
    },
    exportExcel(){
        try {
            const fileName = this.getNowTime()+'.csv';
            const transformData = JSON.parse(JSON.stringify(this.tableData));
            transformData.forEach(item=>item.sn = item.sn.join(""));
            const content = this.arr2CsvString(transformData);
            this.$FileSaver.saveAs(
                new Blob([content], { type: "application/octet-stream" }),
                fileName
            );
        } catch (e) {
            if (typeof console !== "undefined") console.log(e);
        }
    },
    confirmConfig(config){
      this.config = config;
      this.$forceUpdate();
    },
    transformConfig(config){
      config.keyArr.forEach(i=>{
        this.$set(i,'key_led_arr',this.groupArray(i.key_led,5));
        this.$set(i,'key_relay_arr',this.groupArray(i.key_relay,5));
        this.$set(i,'key_led_events',this.getEvents(i.key_led_arr,'LED控制'));
        this.$set(i,'key_relay_events',this.getEvents(i.key_relay_arr,'继电器控制'));
        this.$set(i,'key_code_arr',this.transformKeyCode(i.key_param[4]));
      })
    },
    //不足8位前面补0
    preZero(val){
      let arr = []
      for(let i=0;i<8-val.length;i++){
          arr.push(0);
      }
      return arr.join("")+val
    },
    // 设备键号转换  0-255  0 => 000000000    100 => 01100100    3,6,7
    transformKeyCode(keyCode){
      let hex2String = keyCode.toString(2);
      let midString = this.preZero(hex2String);
      let arr = [];
      for(let i=0;i<8;i++){
        midString[7-i] === '1' && arr.push(i+1+'')
      }
      return arr;
    },
    // 设备键号反转换
    reverseTransformKeyCode(keyCodeArr){
      console.log('start',keyCodeArr);
      let midArr = ['0','0','0','0','0','0','0','0'];
      for(let i=0;i<8;i++){
        keyCodeArr.includes(i+1+'') && (midString[i]='1');
      }
      const midString = midArr.reverse().join('');
      console.log('result',parseInt(midString,2));
      return parseInt(midString,2);
    },
    reverseTransformConfig(config){
      let tempConfig = JSON.parse(JSON.stringify(config));
      tempConfig.keyArr.forEach(item=>{
        item.key_led_arr = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]];
        item.key_relay_arr = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]];
        console.log(item.key_led_arr);
        item.key_led_events.forEach((event,index)=>{
          event.labels.forEach(label=>{
            item.key_led_arr[label-1] = item.key_led_events[index].values;
          })
        })
        item.key_led = this.flatArray(item.key_led_arr);

        item.key_relay_events.forEach((event2,index2)=>{
          event2.labels.forEach(label=>{
            item.key_relay_arr[label-1] = item.key_relay_events[index2].values;
          })
        })
        item.key_relay = this.flatArray(item.key_relay_arr);
        console.log(item.key_code_arr);
        item.key_param[4] = this.reverseTransformKeyCode(item.key_code_arr);
      })
      return tempConfig;
    },
    //获取事件
    getEvents(ledArr,eventLabel){
      const emitEvent = eventLabel === 'LED控制' ? 0 : 1;
      let obj = {};
      let tempArr = [];
      ledArr.forEach((item,index)=>{
        if(item[1] !== 0){
          const tempArrString = JSON.stringify(item);
          if(obj.hasOwnProperty(tempArrString)){
            obj[tempArrString].push(index+1);
          } else {
            obj[tempArrString] = [index+1];
          }
        }
      })
      for(const i in obj){
        const labels = obj[i];
        const values = JSON.parse(i)
        const checkList = this.labels2CheckList(labels);
        const tempObj = {
          labels,
          values,
          eventLabel,
          checkList,
          emitEvent
        }
        tempArr.push(tempObj);
      }
      return tempArr;
    },
    labels2CheckList(labels){
      const checkList = [];
      for(let i=1;i<9;i++){
        if(labels.includes(i)){
          checkList.push('1');
        } else {
          checkList.push('0')
        }
      }
      return checkList;
    },
    //数组扁平化
    flatArray(array){
      const temp = [...array]
      return temp.reduce((result, item)=> {
          return result.concat(Array.isArray(item) ? this.flatArray(item) : item);
      }, []);
    },
    //分割数组
    groupArray(array, subGroupLength){
      let index = 0;
      let newArray = [];
      while(index < array.length) {
          newArray.push(array.slice(index, index += subGroupLength));
      }
      return newArray;
    },
    chooseEquips(ids){
      this.ids = ids;
    },
    changeConfig(item){
      this.chooseConfigName = item.name;
      this.editConfig = true;
      this.config = JSON.parse(item.config);
    },
    chooseConfig(){
      this.editConfig = false;
      this.getConfigList();
    },
    getConfigList(delFlag){
      delFlag && (this.chooseConfigName = '未选择配置');
      this.loading = true;
      let {all} = this;
      let params = {
        all
      }
      this.loadingText = "加载配置中...";
      this.$http.get("/config/list",params).then(res=>{
        this.configList = res.data;
        this.loading = false;
      }).catch(()=>{
        this.loading = false;
      })
    },
    getPortList(){
      this.$lhttp.get("/portlist").then(res=>{
          this.portList = res.data;
      })
    },
    downloadTo(eid,flag){
      if(!this.$store.state.User.status){
        this.$message({
            type: 'error',
            message: "请先搜索设备",
            showClose:true
        })
        return
      }
      if(!eid){
        this.$message({
            type: 'error',
            message: "请选择设备",
            showClose:true
        })
        return
      }
      let { config } = this;
      let newConfig = this.reverseTransformConfig(config);
      
      let params = {
        ...newConfig,eid
      }
      // flag&&(params.paramArr[2] = eid);
      this.loading = true;
      this.loadingText = "下载配置中..."
      this.$lhttp.post('/download_config',params).then(res=>{
        let msg = flag?"设备"+eid+":配置成功":"配置成功";
        this.$message({
          message:msg,
          type:'success',
          showClose:true
        });
        this.loading = false;
      }).catch(_=>{
        this.loading = false;
      })
    },
    downloadTos(){
      if(!this.$store.state.User.status){
        this.$message({
            type: 'error',
            message: "请先搜索设备",
            showClose:true
        })
        return
      }
      if(this.ids.length === 0){
        this.$message({
            type: 'error',
            message: "请选择设备",
            showClose:true
        })
        return
      }
      if(JSON.stringify(this.config) === '{}'){
        this.$message({
            type: 'error',
            message: "请选择配置",
            showClose:true
        })
        return
      }
      this.ids.forEach((item,index)=>{
        setTimeout(()=>{
          this.downloadTo(item,true);
        },500*index);
      })
    },
    delConfig({item,index,eventIndex}){
        this.$confirm('此操作将删除此配置, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
            if(item.emitEvent === 0){
                this.config.keyArr[index].key_led_events.splice(eventIndex,1);
            } else {
                this.config.keyArr[index].key_relay_events.splice(eventIndex,1);
            }
            console.log(this.config);
            this.$message({
                type: 'success',
                message: '删除成功!',
                showClose:true
            });
        })
      },
    downloadConfig(){
      this.$prompt('请输入配置备注', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPattern: /\S/,
        inputErrorMessage: '请输入备注'
      }).then(({ value }) => {
        let config = JSON.stringify(this.config);
        if(config === "{}"){
          this.$message({
            message:"请先配置",
            type:'error',
            showClose:true
          })
          return;
        }
        if(value === ""){
          this.$message({
            message:"请输入配置备注",
            type:'error',
            showClose:true
          })          
          return;
        }
        let name = value;
        const type = "x20";
        let params = {
          config,name,type
        }
        this.$http.post('/config/add',params).then(res=>{
            this.$message({
              message:"保存成功",
              type:"success",
              showClose:true
            });
        })
      })
    },
    chooseEquip(eid){
      this.eid = eid;
      let params = {
        eid
      };
      this.loading = true;
      this.loadingText = "查询配置中...";
      this.$lhttp.get('/equipconfig',params).then(res=>{
        this.config = res.data;
        this.transformConfig(this.config); //转换数组
        this.loading = false;
      }).catch(_=>{
        this.loading = false;
      })
    },
    equipSnSetId(serial_number,eid){
        const data = {
            serial_number,
            eid
        }
        this.$lhttp.post('/equipsnsetid',data).then(res=>{
            // console.log(res);
            // this.equipWhileSn();
            this.$message({
                type: 'success',
                message: '配置ID成功:'+eid,
                showClose:true
            })
            clearInterval(this.whileSnTimer);
            this.whileSnTimer = setInterval(() => {
                this.equipWhileSn();
            }, 500);
        })
    },
    equipWhileSn(){
        if(this.resetIds === ''){
            clearInterval(this.whileSnTimer);
            this.$message({
                type: 'success',
                message: 'ID已被用完,结束配置!',
                showClose:true
            })
            return
        }
        const idsArr = this.resetIds.split(',');

        this.$lhttp.post('/equipwhilesn').then(res=>{
            const sn = res.data;
            const id = parseInt(idsArr.shift());
            // console.log(id);
            this.resetIds = idsArr.join(',')
            const obj = {
                sn,
                id
            }
            this.equipSnSetId(sn,id);
            this.tableData.push(obj);
            clearInterval(this.whileSnTimer);
        }).catch((err)=>{
            console.log(err);
        })
    },
    endWhileSn(){
        this.$lhttp.post('/equipquitsn').then(res=>{
          this.$message({
              type: 'success',
              message: '结束配置成功!',
              showClose:true
          })
        })
        this.$forceUpdate();
        clearInterval(this.whileSnTimer);
    },
    isValidArr(idString){
        let idArr = idString.split(',');
        let newArr = [...new Set(idArr)];
        if(newArr.length === idArr.length){
            for (let i = 0, l = idArr.length; i < l; i++) {
                const id = Number(idArr[i]);
                if(id>254){
                    this.$message({
                        type: 'error',
                        message: 'ID List不合法(范围0-254)',
                        showClose:true
                    })
                    return false;
                }
            }
        }
        return true;
    },
    equipSnPre(){
      // this.tableData = [];
      if(this.equipForm.portModel === ""){
        this.$message({
            type: 'error',
            message: '请选择串口',
            showClose:true
        })
        return;
      }
      if(this.resetIds === ""){
        this.$message({
            type: 'error',
            message: '请输入ID号',
            showClose:true
        })
        return;
      }
      if(!this.isValidArr(this.resetIds)){
          return;
      }
      this.copyResetIds =  this.resetIds;
    //   this.loading = true;
    //   this.loadingText = "搜索设备中...";
      const data = this.equipForm;
      this.$lhttp.post("/equipinitpre",data).then(res=>{
        this.loading = false
        console.log(res);
        this.$message({
            type: 'success',
            message: '进入配置模式成功!',
            showClose:true
        })
        clearInterval(this.whileSnTimer);
        this.whileSnTimer = setInterval(() => {
            this.equipWhileSn();
        }, 500);
      }).catch(()=>{
        this.loading = false
      })
    }
  }
}
</script>

<style lang="scss" scoped>
/deep/ .el-form-item{
  margin-bottom:10px;
}
  .switch-page{
    display: flex;
    height:100%;
    padding:5px;
    background:white;
    box-sizing: border-box;
    .switch-left{
      width:25%;
      background: #FFFFFF;
      border-radius: 10px;
      border: 3px solid #F4F5FE;
    }
    .switch-right{
      flex:1;
      background: #FFFFFF;
      border-radius: 10px;
      border: 3px solid #F4F5FE;
      padding:.8rem;
      height:100%;
      overflow: auto;
    }
  }
</style>